package proxy;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

/**
 * @author fengbo
 * @date 2018/5/15
 */
public class MyClassLoader2 extends ClassLoader {

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        File file = new File("D:\\wwww\\Java\\practice\\com\\sun\\proxy\\$Proxy0.class");
        try {
            byte[] bytes = getClassBytes(file);
            return this.defineClass(name, bytes, 0, bytes.length);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return super.findClass(name);
    }

    private byte[] getClassBytes(File file) throws IOException {
        // 这里要读入.class的字节，因此要使用字节流
        FileInputStream fis = new FileInputStream(file);
        FileChannel fc = fis.getChannel();
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        WritableByteChannel wbc = Channels.newChannel(stream);
        ByteBuffer by = ByteBuffer.allocate(1024);

        while (true) {
            int i = fc.read(by);
            if (i == 0 || i == -1)
                break;
            by.flip();
            wbc.write(by);
            by.clear();
        }
        fis.close();

        return stream.toByteArray();
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException,
            InstantiationException, NoSuchMethodException, InvocationTargetException {
        MyClassLoader2 mcl = new MyClassLoader2();
        Class<?> c1azz = mcl.loadClass(HelloWorld.class.getName());

        Object obj = c1azz.newInstance();
        Method sayHello = c1azz.getMethod("sayHello");
        sayHello.invoke(obj);
    }
}
